<template>
	<template v-for="item in componentList" :key="item.id">
		<template v-if="!item.parentId || parentId">
			<div
				class="chart-item"
				:class="animationsClass(item.styles.animations)"
				:style="{
					...useComponentStyle(item.orgConfig.attr),
					...getTransformStyle(item.styles),
					display: item.status.hide ? 'none' : 'block'
				}"
			>
				<!-- 分组递归调用 -->
				<RenderList v-if="item.isGroup" :list="item.groupList" />
				<component
					v-else
					:is="item.name"
					:ref="(el) => setComponentRefs(el, item)"
					:config="item.orgConfig"
					:id="item.id"
					:style="{ ...useSizeStyle(item.orgConfig.attr) }"
					:update="useInterData(item.id, item.orgConfig)"
					:show="() => changeShow(item, 'show')"
					:hide="() => changeShow(item, 'hide')"
					:changShow="() => changeShow(item, 'change')"
					:customEvent="customEvent"
					v-show="item.show"
					v-on="useEventHandler(item.id, $store.chart.RenderComponentList, item.orgConfig)"
				/>
			</div>
		</template>
	</template>
</template>

<script setup name="RenderList">
import { animationsClass, getTransformStyle, useSizeStyle, useComponentStyle } from '@/utils';
import { useEventHandler } from './hooks/useEventHandler.hook';
import { useInterData } from './hooks/useInterData.hook';

const props = defineProps({
		parentId: {
			type: String,
			default: ''
		},
		list: {
			type: Array
		}
	}),
	componentList = computed(() => {
		if (props.parentId) return $store.chart.RenderComponentList.filter((item) => item.parentId === props.parentId);
		return props.list || $store.chart.RenderComponentList;
	});

/**
 * 全局存储所有的组件ref，使用debounced函数避免执行两次的问题
 */
const componentRefs = {},
	debounced = debounce(() => {
		$store.chart.componentRefs = Object.assign($store.chart.componentRefs, componentRefs);
	}, 100);
function setComponentRefs(el, item) {
	const isHas = componentRefs[item.id];
	!isHas && (componentRefs[item.id] = el);
	debounced();
}

// 自组件的自定义函数
async function customEvent(fnStr, ref) {
	let newFn = new Function('ref', fnStr);
	newFn(ref);
}

// 组件的隐藏显示
function changeShow(item, type) {
	switch (type) {
		case 'change':
			item.show = !item.show;
			break;
		case 'hide':
			item.show = false;
			break;
		case 'show':
			item.show = true;
			break;
		default:
			break;
	}
}
</script>

<style lang="scss" scoped>
.chart-item {
	position: absolute;
}
</style>
